package ru.mcfr.oxygen.plugin.workspace;

import org.apache.log4j.Logger;
import ro.sync.ecss.extensions.api.AuthorDocumentController;
import ro.sync.ecss.extensions.api.AuthorOperationException;
import ro.sync.ecss.extensions.api.node.AuthorDocumentFragment;
import ro.sync.ecss.extensions.api.node.AuthorElement;
import ro.sync.ecss.extensions.api.node.AuthorNode;
import ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension;
import ro.sync.exml.workspace.api.editor.WSEditor;
import ro.sync.exml.workspace.api.editor.page.WSEditorPage;
import ro.sync.exml.workspace.api.editor.page.author.WSAuthorEditorPage;
import ro.sync.exml.workspace.api.editor.page.text.WSTextEditorPage;
import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace;
import ro.sync.exml.workspace.api.standalone.ToolbarComponentsCustomizer;
import ro.sync.exml.workspace.api.standalone.ToolbarInfo;
import ro.sync.exml.workspace.api.standalone.ui.ToolbarButton;
import ru.mcfr.oxygen.util.BareBonesBrowserLaunch;
import ru.mcfr.oxygen.util.FillIDs;
import ru.mcfr.oxygen.util.ui.SchemaSelectorWindow;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.InvalidPropertiesFormatException;
import java.util.List;
import java.util.Properties;

public class CustomWorkspaceAccessPluginExtension implements WorkspaceAccessPluginExtension {

    private boolean runPlugin;

    private static Logger logger = Logger.getLogger(CustomWorkspaceAccessPluginExtension.class.getName());

    private StandalonePluginWorkspace ins = null;

    private Properties props = new Properties();
    private String infos = "";

    private void doFillIDs() {

        WSEditor editorAccess = ins.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);
        WSEditorPage purePage = editorAccess.getCurrentPage();

        try {//author window
            FillIDs fillID = new FillIDs();

            AuthorDocumentController docController = ((WSAuthorEditorPage) purePage).getDocumentController();
            int caretPosition = ((WSAuthorEditorPage) purePage).getCaretOffset();

            docController.beginCompoundEdit();

            try {
                AuthorNode[] nodes = docController.findNodesByXPath("/документ/*[not(self::метаданные)]", false, false, false);
                for (AuthorNode node : nodes) {
                    AuthorElement ae = (AuthorElement) node;
                    if (node.getType() == AuthorNode.NODE_TYPE_ELEMENT) {
                        //just replace fragment. id will filled in framework
                        if (!fillID.lostElements.contains(ae.getName())) {
                            int position = node.getStartOffset();
                            AuthorDocumentFragment docFragment = docController.createDocumentFragment(node, true);
                            docController.deleteNode(node);
                            docController.insertFragment(position, docFragment);
                        }
                    }
                }
            } catch (AuthorOperationException e) {
                ins.showStatusMessage(e.getMessage());
            } finally {
                docController.endCompoundEdit();
            }

            ((WSAuthorEditorPage) purePage).setCaretPosition(caretPosition);
        } catch (Exception e) {
            ins.showStatusMessage(e.getMessage());
        }

        try {//text window

            FillIDs fillID = new FillIDs();

            JTextArea textArea = (JTextArea) ((WSTextEditorPage) purePage).getTextComponent();
            int currentPosition = textArea.getCaretPosition();

            String docText = textArea.getText();

            String filledXMLText = fillID.fillXML(docText);

            textArea.replaceRange(filledXMLText, 0, docText.length());
            textArea.setCaretPosition(currentPosition);
        } catch (Exception e) {
            ins.showStatusMessage(e.getMessage());
        }
        ins.showStatusMessage("Заполение id выполнено.");

    }

    public void applicationStarted(final StandalonePluginWorkspace pluginWorkspaceAccess) {

        URL resource = getClass().getResource("/" + getClass().getName().replace('.', '/') + ".class");
        this.ins = pluginWorkspaceAccess;

        this.runPlugin = "jar".equals(resource.getProtocol()) ? true : System.getProperty("ru.mcfr.fillID") != null;
        if (runPlugin) {

            String baseDir = WorkspaceAccessPlugin.getInstance().getDescriptor().getBaseDir().getAbsolutePath();

            if ((new File(baseDir + File.separator + "settings.xml")).exists())
                try {
                    props.loadFromXML((new File(baseDir + File.separator + "settings.xml")).toURI().toURL().openStream());
                } catch (InvalidPropertiesFormatException e1) {
                    logger.error(e1);
                } catch (MalformedURLException e1) {
                    logger.error(e1);
                } catch (IOException e1) {
                    logger.error(e1);
                }
            else
                try {
                    props.setProperty("proxy-ip", "");
                    props.setProperty("use-proxy", "");
                    props.setProperty("proxy-user-name", "");
                    props.setProperty("proxy-user-pass", "");
                    props.setProperty("url-to-docTypes", "");
                    props.setProperty("url-to-shemas", "");
                    props.setProperty("cms-url", "http://194.28.21.168/");
                    props.storeToXML(new FileOutputStream(new File(baseDir + File.separator + "settings.xml")), "init");
                } catch (FileNotFoundException e2) {
                    logger.error(e2);
                } catch (IOException e2) {
                    logger.error(e2);
                }
        }

        final Action fillIDAction = new AbstractAction() {
            public void actionPerformed(ActionEvent arg0) {
                doFillIDs();
            }
        };

        final Action shemaManager = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {

                WSEditor editorAccess = ins.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);
                WSEditorPage purePage = editorAccess.getCurrentPage();

                try {
                    AuthorDocumentController docController = ((WSAuthorEditorPage) purePage).getDocumentController();
                    SchemaSelectorWindow wnd = new SchemaSelectorWindow(props, docController);
                    wnd.showDialog();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        };

        final Action browseAction = new AbstractAction() {
            public void actionPerformed(ActionEvent arg0) {
                BareBonesBrowserLaunch.openURL(props.getProperty("cms-url", "http://194.28.21.168/"));
            }
        };

        pluginWorkspaceAccess.addToolbarComponentsCustomizer(new ToolbarComponentsCustomizer() {
            public void customizeToolbar(ToolbarInfo toolbarInfo) {
                if (ToolbarComponentsCustomizer.CUSTOM.equals(toolbarInfo.getToolbarID())) {

                    ToolbarButton fillButton = new ToolbarButton(fillIDAction, true);
                    fillButton.setText("Заполнить id");

                    ToolbarButton schemaButton = new ToolbarButton(shemaManager, true);
                    schemaButton.setText("Назначить схему");

                    ToolbarButton openFenomen = new ToolbarButton(browseAction, true);
                    openFenomen.setText("ФЕНОМЕН");

                    List<JComponent> comps = new ArrayList<JComponent>();
                    comps.add(fillButton);
                    comps.add(schemaButton);

                    toolbarInfo.setComponents(comps.toArray(new JComponent[comps.size()]));
                    toolbarInfo.setTitle("Редактор");

                }
            }
        });
    }

    public boolean applicationClosing() {
        return true;
    }

}
